package Or

import (
	"context"
	"errors"
	"fmt"
	"db2s/dbPar"
	"db2s/global"
	"db2s/go-log/log"
	"db2s/outPut"
	"db2s/parDef"
	"db2s/ref"
	"reflect"
	"strings"
	"sync/atomic"
)

func newTimeTypeToFunc(colMap, columnName, asColumn string) (r string) {
	switch colMap {
	case "year-month-day hour:minute:second":
		r = fmt.Sprintf("to_char(%s,'YYYY-MM-DD HH24:MI:SS') as \"%v\"", columnName, asColumn)
	case "year-month-day hour:minute:second.utc":
		r = fmt.Sprintf("to_char(%s,'YYYY-MM-DD HH24:MI:SS TZR') as \"%v\"", columnName, asColumn)
	case "year-month-day hour:minute:second.milli(1)":
		r = fmt.Sprintf("to_char(%s,'YYYY-MM-DD HH24:MI:SS.FF%d') as \"%v\"", columnName, 1, asColumn)
	case "year-month-day hour:minute:second.milli(1).utc":
		r = fmt.Sprintf("to_char(%s,'YYYY-MM-DD HH24:MI:SS.FF%d TZR') as \"%v\"", columnName, 1, asColumn)
	case "year-month-day hour:minute:second.milli(2)":
		r = fmt.Sprintf("to_char(%s,'YYYY-MM-DD HH24:MI:SS.FF%d') as \"%v\"", columnName, 2, asColumn)
	case "year-month-day hour:minute:second.milli(2).utc":
		r = fmt.Sprintf("to_char(%s,'YYYY-MM-DD HH24:MI:SS.FF%d TZR') as \"%v\"", columnName, 2, asColumn)
	case "year-month-day hour:minute:second.milli(3)":
		r = fmt.Sprintf("to_char(%s,'YYYY-MM-DD HH24:MI:SS.FF%d') as \"%v\"", columnName, 3, asColumn)
	case "year-month-day hour:minute:second.milli(3).utc":
		r = fmt.Sprintf("to_char(%s,'YYYY-MM-DD HH24:MI:SS.FF%d TZR') as \"%v\"", columnName, 3, asColumn)
	case "year-month-day hour:minute:second.micro(1)":
		r = fmt.Sprintf("to_char(%s,'YYYY-MM-DD HH24:MI:SS.FF%d') as \"%v\"", columnName, 4, asColumn)
	case "year-month-day hour:minute:second.micro(1).utc":
		r = fmt.Sprintf("to_char(%s,'YYYY-MM-DD HH24:MI:SS.FF%d TZR') as \"%v\"", columnName, 4, asColumn)
	case "year-month-day hour:minute:second.micro(2)":
		r = fmt.Sprintf("to_char(%s,'YYYY-MM-DD HH24:MI:SS.FF%d') as \"%v\"", columnName, 5, asColumn)
	case "year-month-day hour:minute:second.micro(2).utc":
		r = fmt.Sprintf("to_char(%s,'YYYY-MM-DD HH24:MI:SS.FF%d TZR') as \"%v\"", columnName, 5, asColumn)
	case "year-month-day hour:minute:second.micro(3)":
		r = fmt.Sprintf("to_char(%s,'YYYY-MM-DD HH24:MI:SS.FF%d') as \"%v\"", columnName, 6, asColumn)
	case "year-month-day hour:minute:second.micro(3).utc":
		r = fmt.Sprintf("to_char(%s,'YYYY-MM-DD HH24:MI:SS.FF%d TZR') as \"%v\"", columnName, 6, asColumn)
	case "year-month-day hour:minute:second.nano(1)":
		r = fmt.Sprintf("to_char(%s,'YYYY-MM-DD HH24:MI:SS.FF%d') as \"%v\"", columnName, 7, asColumn)
	case "year-month-day hour:minute:second.nano(1).utc":
		r = fmt.Sprintf("to_char(%s,'YYYY-MM-DD HH24:MI:SS.FF%d TZR') as \"%v\"", columnName, 7, asColumn)
	case "year-month-day hour:minute:second.nano(2)":
		r = fmt.Sprintf("to_char(%s,'YYYY-MM-DD HH24:MI:SS.FF%d') as \"%v\"", columnName, 8, asColumn)
	case "year-month-day hour:minute:second.nano(2).utc":
		r = fmt.Sprintf("to_char(%s,'YYYY-MM-DD HH24:MI:SS.FF%d TZR') as \"%v\"", columnName, 8, asColumn)
	case "year-month-day hour:minute:second.nano(3)":
		r = fmt.Sprintf("to_char(%s,'YYYY-MM-DD HH24:MI:SS.FF%d') as \"%v\"", columnName, 9, asColumn)
	case "year-month-day hour:minute:second.nano(3).utc":
		r = fmt.Sprintf("to_char(%s,'YYYY-MM-DD HH24:MI:SS.FF%d TZR') as \"%v\"", columnName, 9, asColumn)
	default:
		r = fmt.Sprintf("to_char(%s,'YYYY-MM-DD HH24:MI:SS') as \"%v\"", columnName, asColumn)
	}
	return
}
func newTimeValueToFunc(colMap, value string) (r string) {
	switch colMap {
	case "year-month-day hour:minute:second":
		r = fmt.Sprintf("to_date(%s,'YYYY-MM-DD HH24:MI:SS')", value)
	case "year-month-day hour:minute:second.utc":
		r = fmt.Sprintf("to_timestamp(%s,'YYYY-MM-DD HH24:MI:SS TZR')", value)
	case "year-month-day hour:minute:second.milli(1)":
		r = fmt.Sprintf("to_timestamp(%s,'YYYY-MM-DD HH24:MI:SS.FF%d')", value, 1)
	case "year-month-day hour:minute:second.milli(1).utc":
		r = fmt.Sprintf("to_timestamp(%s,'YYYY-MM-DD HH24:MI:SS.FF%d TZR')", value, 1)
	case "year-month-day hour:minute:second.milli(2)":
		r = fmt.Sprintf("to_timestamp(%s,'YYYY-MM-DD HH24:MI:SS.FF%d')", value, 2)
	case "year-month-day hour:minute:second.milli(2).utc":
		r = fmt.Sprintf("to_timestamp(%s,'YYYY-MM-DD HH24:MI:SS.FF%d TZR')", value, 2)
	case "year-month-day hour:minute:second.milli(3)":
		r = fmt.Sprintf("to_timestamp(%s,'YYYY-MM-DD HH24:MI:SS.FF%d')", value, 3)
	case "year-month-day hour:minute:second.milli(3).utc":
		r = fmt.Sprintf("to_timestamp(%s,'YYYY-MM-DD HH24:MI:SS.FF%d TZR')", value, 3)
	case "year-month-day hour:minute:second.micro(1)":
		r = fmt.Sprintf("to_timestamp(%s,'YYYY-MM-DD HH24:MI:SS.FF%d')", value, 4)
	case "year-month-day hour:minute:second.micro(1).utc":
		r = fmt.Sprintf("to_timestamp(%s,'YYYY-MM-DD HH24:MI:SS.FF%d TZR')", value, 4)
	case "year-month-day hour:minute:second.micro(2)":
		r = fmt.Sprintf("to_timestamp(%s,'YYYY-MM-DD HH24:MI:SS.FF%d')", value, 5)
	case "year-month-day hour:minute:second.micro(2).utc":
		r = fmt.Sprintf("to_timestamp(%s,'YYYY-MM-DD HH24:MI:SS.FF%d TZR')", value, 5)
	case "year-month-day hour:minute:second.micro(3)":
		r = fmt.Sprintf("to_timestamp(%s,'YYYY-MM-DD HH24:MI:SS.FF%d')", value, 6)
	case "year-month-day hour:minute:second.micro(3).utc":
		r = fmt.Sprintf("to_timestamp(%s,'YYYY-MM-DD HH24:MI:SS.FF%d TZR')", value, 6)
	case "year-month-day hour:minute:second.nano(1)":
		r = fmt.Sprintf("to_timestamp(%s,'YYYY-MM-DD HH24:MI:SS.FF%d')", value, 7)
	case "year-month-day hour:minute:second.nano(1).utc":
		r = fmt.Sprintf("to_timestamp(%s,'YYYY-MM-DD HH24:MI:SS.FF%d TZR')", value, 7)
	case "year-month-day hour:minute:second.nano(2)":
		r = fmt.Sprintf("to_timestamp(%s,'YYYY-MM-DD HH24:MI:SS.FF%d')", value, 8)
	case "year-month-day hour:minute:second.nano(2).utc":
		r = fmt.Sprintf("to_timestamp(%s,'YYYY-MM-DD HH24:MI:SS.FF%d TZR')", value, 8)
	case "year-month-day hour:minute:second.nano(3)":
		r = fmt.Sprintf("to_timestamp(%s,'YYYY-MM-DD HH24:MI:SS.FF%d')", value, 9)
	case "year-month-day hour:minute:second.nano(3).utc":
		r = fmt.Sprintf("to_timestamp(%s,'YYYY-MM-DD HH24:MI:SS.FF%d TZR')", value, 9)
	default:
		r = fmt.Sprintf("to_date(%s,'YYYY-MM-DD HH24:MI:SS')", value)
	}
	return
}
func newParameterFmToString(n int64, p string) string {
	var s []string
	if n > 38 {
		n = 38
	}
	for i := int64(0); i < n; i++ {
		s = append(s, p)
	}
	if len(s) == 0 {
		return ""
	}
	return fmt.Sprintf("%v", strings.Join(s, ""))
}
func newScaleFmToString(n int64, p string) string {
	var s []string
	if n > 38 {
		n = 38
	}
	for i := int64(0); i < n; i++ {
		s = append(s, p)
	}
	if len(s) == 0 {
		return ""
	}
	return fmt.Sprintf(".%v", strings.Join(s, ""))
}
func newDecimalTypeToFunc(precision, scale int64, colMap, columnName, asColumn string) (r string) {
	switch colMap {
	case "decimal(precision,scale)":
		r = fmt.Sprintf("to_char(%s,'FM%s0%s') as \"%v\" ", columnName, newParameterFmToString(precision-scale, "9"), newScaleFmToString(scale, "0"), asColumn)
	case "decimal(max,max)":
		r = fmt.Sprintf("to_char(%s) as \"%v\" ", columnName, asColumn)
	default:
		r = fmt.Sprintf("%v as \"%v\"", columnName, asColumn)
	}
	return
}

func NewSpecialTypeToFunc(LockCol parDef.Encryption, colMap parDef.ColMetaMapS) (r string) {
	asColumn := fmt.Sprintf("C%v", colMap.ColumnSeq)
	var unlockFunc string
	for _, v := range LockCol.Column {
		if strings.EqualFold(v, colMap.ColumnName) && len(LockCol.UnlockFunc) > 0 {
			unlockFunc = fmt.Sprintf("%v.%v(\"%v\")", LockCol.Schema, LockCol.UnlockFunc, colMap.ColumnName)
			break
		}
	}
	if len(unlockFunc) == 0 {
		unlockFunc = fmt.Sprintf("\"%v\"", colMap.ColumnName)
	}
	switch colMap.TypeBelong {
	case "time", "timestamp":
		return newTimeTypeToFunc(colMap.Type.ColTypeMap, unlockFunc, asColumn)
	case "decimal":
		return newDecimalTypeToFunc(colMap.Type.Precision, colMap.Type.Scale, colMap.Type.ColTypeMap, unlockFunc, asColumn)
	case "char":
		return fmt.Sprintf("%s as \"%v\"", unlockFunc, asColumn)
		//return fmt.Sprintf("rtrim(%s) as \"%v\"", unlockFunc, asColumn)
	case "gis":
		return fmt.Sprintf(" \nCASE \n    "+
			"WHEN %v IS NOT NULL \n    "+
			"THEN \n"+
			"MDSYS.SDO_UTIL.TO_WKTGEOMETRY(%v) || '@STYPE:' || T.%v.SDO_GTYPE || ',' || 'SRID:' || T.%v.SDO_SRID || ',' || 'AXIS:EPSG' \n    "+
			"ELSE NULL \n  "+
			"END AS %v ",
			unlockFunc, unlockFunc, unlockFunc, unlockFunc, asColumn)
	default:
		return fmt.Sprintf("%v as \"%v\"", unlockFunc, asColumn)
	}
}

// NewSpecialCharValueToFunc 根据列的数据类型，将字符串值继续函数转换
func NewSpecialCharValueToFunc(colMap parDef.ColMetaMapS, value string) (newValue string) {
	newValue = fmt.Sprintf("'%v'", strings.ReplaceAll(value, "'", "\\'"))
	switch colMap.TypeBelong {
	case "time", "timestamp":
		return newTimeValueToFunc(colMap.Type.ColTypeMap, newValue)
	default:
		switch {
		case strings.EqualFold(colMap.ColumnName, "rowId"):
			newValue = value
		case strings.EqualFold(newValue, "NULL"):
			newValue = value
		}
		return
	}
}
func newHitSpecify(indexName, partitionName string) (hitIndexName string) {
	//指定partition name会导致无法使用索引，进行全表扫描，且该sql为查询数据，已经通过索引列范围确定查询范围，所以不需要指定分区
	if len(indexName) > 0 && !strings.EqualFold(partitionName, "single") && len(partitionName) > 0 {
		hitIndexName = fmt.Sprintf(" /*+ index(T %v) */ ", indexName)
	}
	return
}

func newLeftStitching(s parDef.WhereGenerateInput) (l string) {
	var whereLeft []string
	for _, v := range func() []map[string]string {
		if len(s.NewLeftDirection) > 0 {
			return s.NewLeftDirection
		}
		return getAtomicValue(s.LeftDirection)
	}() {
		columnName, nLeftOk := v["columnName"]
		columnDataLeft, cLeftOk := v["columnDataLeft"]
		querySymbolLeft, qLeftOk := v["querySymbolLeft"]
		if cLeftOk && qLeftOk && nLeftOk {
			if strings.EqualFold(querySymbolLeft, "=") && strings.EqualFold(columnDataLeft, "NULL") { //处理等值null
				whereLeft = append(whereLeft, fmt.Sprintf("\"%s\" %s %s", columnName, " IS ", columnDataLeft))
			} else if strings.EqualFold(querySymbolLeft, ">") && strings.EqualFold(columnDataLeft, "NULL") {
				whereLeft = append(whereLeft, fmt.Sprintf("\"%s\" %s %s", columnName, " IS NOT ", columnDataLeft))
			} else {
				whereLeft = append(whereLeft, fmt.Sprintf("\"%s\" %s %s", columnName, querySymbolLeft, NewSpecialCharValueToFunc(getSpecialColNameMetaMap(columnName, s.ColMetaMap), columnDataLeft)))
			}
		}
	}
	return strings.Join(whereLeft, " and ")
}
func getSpecialColNameMetaMap(name string, colMeta []parDef.ColMetaMapS) (r parDef.ColMetaMapS) {
	for _, col := range colMeta {
		if strings.EqualFold(col.ColumnName, name) {
			return col
		}
	}
	return
}
func newRightStitching(s parDef.WhereGenerateInput) string {
	var whereRight []string
	for _, v := range func() []map[string]string {
		if len(s.NewRightDirection) > 0 {
			return s.NewRightDirection
		}
		return getAtomicValue(s.RightDirection)
	}() {
		columnName, nRightOk := v["columnName"]
		columnDataRight, cRightOk := v["columnDataRight"]
		querySymbolRight, qRightOk := v["querySymbolRight"]
		if cRightOk && qRightOk && nRightOk {
			if strings.EqualFold(querySymbolRight, "=") && strings.EqualFold(columnDataRight, "NULL") {
				whereRight = append(whereRight, fmt.Sprintf("\"%s\" %s %s", columnName, " IS ", columnDataRight))
			} else if strings.EqualFold(querySymbolRight, ">") && strings.EqualFold(columnDataRight, "NULL") {
				whereRight = append(whereRight, fmt.Sprintf("\"%s\" %s %s", columnName, " IS NOT ", columnDataRight))
			} else {
				whereRight = append(whereRight, fmt.Sprintf("\"%s\" %s %s", columnName, querySymbolRight, NewSpecialCharValueToFunc(getSpecialColNameMetaMap(columnName, s.ColMetaMap), columnDataRight)))
			}
		}
	}
	return strings.Join(whereRight, " and ")
}
func newWhereGenerate(whereSql string, s parDef.WhereGenerateInput) (ConditionSlice []string, err error) {
	if len(whereSql) > 0 {
		ConditionSlice = append(ConditionSlice, whereSql)
		return
	}
	if v := newLeftStitching(s); len(v) > 0 {
		ConditionSlice = append(ConditionSlice, v)
	}
	if v := newRightStitching(s); len(v) > 0 {
		ConditionSlice = append(ConditionSlice, v)
	}
	return
}
func newOrderBY(s parDef.WhereGenerateInput) (res string, err error) {
	var orderByColumn []string
	if strings.EqualFold(s.NullConstraint, "null") {
		return
	}
	var uniqOrderByColumn = make(map[string]int)
	for _, v := range s.IndexColumn {
		for _, v1 := range getAtomicValue(s.LeftDirection) {
			if v2, ok := v1["columnName"]; ok {
				if strings.EqualFold(v, v2) {
					if _, ok2 := uniqOrderByColumn[v]; !ok2 {
						uniqOrderByColumn[v]++
						orderByColumn = append(orderByColumn, v)
					}
				}
			}
		}
	}
	if len(orderByColumn) > 0 {
		return fmt.Sprintf("order by \"%v\"", strings.Join(orderByColumn, "\",\"")), nil
	}
	return
}
func newResultCol(asSelectColumn []string, tableAS string) (r string) {
	var l []string
	for _, v := range asSelectColumn {
		l = append(l, fmt.Sprintf("%v.\"%v\" ", tableAS, v))
	}
	return strings.Join(l, ",")
}
func newSelectCol(selectC []string) (r string) {
	var selectIndexColumn []string
	for _, v := range selectC {
		selectIndexColumn = append(selectIndexColumn, fmt.Sprintf("\"%v\"", v))
	}
	return strings.Join(selectIndexColumn, ",")
}
func newOrderByNull(nullBool *int32, indexCol []string) (r string) {
	var nullOrderDesc []string
	for k, v := range indexCol {
		if k > 0 && atomic.LoadInt32(nullBool) == 1 {
			nullOrderDesc = append(nullOrderDesc, fmt.Sprintf("\"%v\" ASC NULLS FIRST", v))
		} else {
			nullOrderDesc = append(nullOrderDesc, fmt.Sprintf("\"%v\"", v))
		}
	}
	return fmt.Sprintf(" order by %v", strings.Join(nullOrderDesc, ","))
}
func newWhereSplicing(whereCondition []string) (r string) {
	if len(whereCondition) > 0 {
		return fmt.Sprintf(" where %v", strings.Join(whereCondition, " and "))
	}
	return
}
func getIndexColMetaCharset(ctx context.Context) (collation string, compareVal []string) {
	switch meta := parDef.GetFuncParameterValue(ctx, parDef.GetMetaParameterValue()); meta.(type) {
	case map[string][]string:
		for col, val := range meta.(map[string][]string) {
			for _, subCol := range parDef.GetFuncParameterValue(ctx, parDef.GetTableIndexColumnMapParameterValue()).([]parDef.IdxSubColumnMe) {
				if strings.EqualFold(col, subCol.ColumnName) {
					collation = subCol.Collation
					compareVal = val
					break
				}
			}
		}
	}
	return
}
func getColCharacterVarchar(ctx context.Context) (newCompareVal []string) {
	var collation, compareVal = getIndexColMetaCharset(ctx)
	for _, v := range compareVal {
		var notNullVal = v
		if strings.EqualFold(v, "<null>") {
			notNullVal = "NULL"
		}
		newCompareVal = append(newCompareVal, fmt.Sprintf("NLSSORT('%v', 'NLS_SORT = %v')", notNullVal, collation))
	}
	return
}
func (rows RowsF) getInsertIntoColumnPrefix(ctx context.Context) (insertColumn [][]string, err error) {
	var result global.Return
	var event = "[getInsertIntoColumnPrefix]"
	if result, err = rows.InsertAllCol(ctx); err != nil {
		err = ref.ErrAddPrintf(event, err)
		return
	}
	switch result.Result.(type) {
	case [][]string:
		insertColumn = result.Result.([][]string)
	default:
		err = ref.ErrAddPrintf(event, errors.New(fmt.Sprintf("type not match. curry type is %v", reflect.TypeOf(result.Result))))
	}
	return
}
func (rows RowsF) Prefix(ctx context.Context) (result global.Return, err error) {
	var event = "[Prefix]"
	var tableName, ignoreStr string
	var insertColumn [][]string
	defer func() {
		if r := ref.RecoverPanic(event, recover()); err == nil && r != nil {
			err = r
		}
	}()
	return ctxDoneExecFunc(ctx, func() (global.Return, error) {
		if insertColumn, err = rows.getInsertIntoColumnPrefix(ctx); err != nil {
			err = ref.ErrAddPrintf(event, err)
			return result, err
		}
		var schema, table = parDef.GetExecFuncParameterValueBase(ctx)
		tableName = fmt.Sprintf(" \"%v\".\"%v\" ", schema, table)
		result.Result = fmt.Sprintf("%s ", fmt.Sprintf("INSERT %v INTO %v (\"%s\") VALUES", ignoreStr, tableName, strings.Join(insertColumn[0], "\",\"")))
		if parDef.GetParameterValueAnyToBool(parDef.GetFuncParameterValue(ctx, "lobTableLogo")) {
			var s1 []string
			for i := 0; i < len(insertColumn[0]); i++ {
				s1 = append(s1, "?")
			}
			result.Result = fmt.Sprintf("INSERT INTO %v (\"%s\") VALUES (%s)", tableName, strings.Join(insertColumn[0], "\",\""), strings.Join(s1, ","))
		}
		return result, err
	})
}

func (rows RowsF) writeFileDML(event string, ctx context.Context) (result global.Return, err error) {
	event = fmt.Sprintf("%v -> writeFileDML", event)
	defer func() {
		if r := ref.RecoverPanic(event, recover()); err == nil && r != nil {
			err = r
		}
	}()
	return ctxDoneExecFunc(ctx, func() (global.Return, error) {
		var schemaTable = getTableName(parDef.GetExecFuncParameterValueBase(ctx))
		result.Sql = parDef.GetParameterValueAnyToString(parDef.GetFuncParameterValue(ctx, parDef.GetDMLSqlParameterValue()))
		var DMLSqlFilePoint = parDef.GetFuncParameterValue(ctx, parDef.GetDMLSqlFilePointParameterValue())
		log.MainLog().Debug(event, schemaTable, fmt.Sprintf(" sql is %v.", result.Sql))
		if DMLSqlFilePoint == nil {
			err = ref.ErrAddPrintf(event, fmt.Errorf("file point is nil"))
			log.ErrorLog().Error(event, schemaTable, fmt.Sprintf(" sql is %v, error is %v.", result.Sql, err))
			return result, err
		}
		if err = DMLSqlFilePoint.(outPut.FileOperations).Write("", result.Sql); err != nil {
			err = ref.ErrAddPrintf(event, err)
			log.ErrorLog().Error(event, schemaTable, fmt.Sprintf(" sql is %v,file name is %v error is %v.", result.Sql, DMLSqlFilePoint.(outPut.FileOperations).Print(outPut.FileName), err))
			return result, err
		}
		log.MainLog().Debug(event, schemaTable, fmt.Sprintf(" sql is %v, file name is %v bath timeOut is %v ms.", result.Sql, DMLSqlFilePoint.(outPut.FileOperations).Print(outPut.FileName), result.TimeOut))
		return result, err
	})
}

func (rows RowsF) connExecDML(event string, ctx context.Context) (result global.Return, err error) {
	event = fmt.Sprintf("%v -> connExecDML", event)
	defer func() {
		if r := ref.RecoverPanic(event, recover()); err == nil && r != nil {
			err = r
		}
	}()
	return ctxDoneExecFunc(ctx, func() (global.Return, error) {
		result.Sql = parDef.GetParameterValueAnyToString(parDef.GetFuncParameterValue(ctx, parDef.GetDMLSqlParameterValue()))
		result.TimeOut, err = newExecUpdateSql(event, getTableName(parDef.GetExecFuncParameterValueBase(ctx)), parDef.GetReadExecSqlFuncOptionsValueBase(ctx), []string{result.Sql})
		return result, err
	})
}

func (rows RowsF) ExecDML(ctx context.Context) (result global.Return, err error) {
	var event = "[ExecDML]"
	defer func() {
		if r := ref.RecoverPanic(event, recover()); err == nil && r != nil {
			err = r
		}
	}()
	return ctxDoneExecFunc(ctx, func() (global.Return, error) {
		switch repairMethod := parDef.GetParameterValueAnyToString(parDef.GetFuncParameterValue(ctx, parDef.GetRepairMethodParameterValue())); repairMethod {
		case "table":
			return rows.connExecDML(event, ctx)
		case "file":
			return rows.writeFileDML(event, ctx)
		default:
			err = ref.ErrAddPrintf(event, fmt.Errorf(fmt.Sprintf("expect value not matched. curry value is %v expect value is %v", repairMethod, []string{"table", "file"})))
			log.ErrorLog().Error(event, getTableName(parDef.GetExecFuncParameterValueBase(ctx)), fmt.Sprintf(" error is %v.", err))
		}
		log.MainLog().Debug(event, getTableName(parDef.GetExecFuncParameterValueBase(ctx)), "The ddl sql execution has been completed.")
		return result, err
	})
}
func (rows RowsF) SelectIdxCol(ctx context.Context) (result global.Return, err error) {
	var event = "[SelectIdxCol]"
	defer func() {
		if r := ref.RecoverPanic(event, recover()); err == nil && r != nil {
			err = r
		}
	}()
	return ctxDoneExecFunc(ctx, func() (global.Return, error) {
		var columnName, asColumnName []string
		for _, i := range parDef.GetParameterValueAnyToStringGarth(parDef.GetFuncParameterValue(ctx, parDef.GetIndexColumnNameParameterValue())) {
			p := getSpecialColNameMetaMap(i, parDef.GetFuncParameterValue(ctx, parDef.GetTableColumnMapParameterValue()).([]parDef.ColMetaMapS))
			asColumnName = append(asColumnName, fmt.Sprintf("C%v", p.ColumnSeq))
			columnName = append(columnName, NewSpecialTypeToFunc(parDef.GetFuncParameterValue(ctx, parDef.GetTableLockColumnFuncParameterValue()).(parDef.Encryption), p))
		}
		result.Result = [][]string{columnName, asColumnName}
		return result, err
	})
}
func (rows RowsF) SelectAllCol(ctx context.Context) (result global.Return, err error) {
	var columnName, asColumnName []string
	var event = "[SelectAllCol]"
	defer func() {
		if r := ref.RecoverPanic(event, recover()); err == nil && r != nil {
			err = r
		}
	}()
	return ctxDoneExecFunc(ctx, func() (global.Return, error) {
		for _, v := range parDef.GetFuncParameterValue(ctx, parDef.GetTableColumnMapParameterValue()).([]parDef.ColMetaMapS) {
			asColumnName = append(asColumnName, fmt.Sprintf("C%v", v.ColumnSeq))
			columnName = append(columnName, NewSpecialTypeToFunc(parDef.GetFuncParameterValue(ctx, parDef.GetTableLockColumnFuncParameterValue()).(parDef.Encryption), v))
		}
		result.Result = columnName
		return result, err
	})
}
func (rows RowsF) InsertAllCol(ctx context.Context) (result global.Return, err error) {
	var columnNameAndType [][]string
	var event = "[InsertAllCol]"
	defer func() {
		if r := ref.RecoverPanic(event, recover()); err == nil && r != nil {
			err = r
		}
	}()
	return ctxDoneExecFunc(ctx, func() (global.Return, error) {
		switch meta := parDef.GetFuncParameterValue(ctx, parDef.GetMetaParameterValue()); meta.(type) {
		case []parDef.ColMetaMapS:
			var columnName, columnType []string
			for _, v := range meta.([]parDef.ColMetaMapS) {
				columnName = append(columnName, v.ColumnName)
				columnType = append(columnType, v.TypeBelong)
			}
			columnNameAndType = append(columnNameAndType, columnName, columnType)
		}
		result.Result = columnNameAndType
		return result, err
	})
}

func (rows RowsF) StringValueCompare(ctx context.Context) (result global.Return, err error) {
	var event = "[StringValueCompare]"
	defer func() {
		if r := ref.RecoverPanic(event, recover()); err == nil && r != nil {
			err = r
		}
	}()
	var newCompareVal = getColCharacterVarchar(ctx)
	var _, table = parDef.GetExecFuncParameterValueBase(ctx)
	select {
	case <-ctx.Done():
		err = ctx.Err()
		return
	default:
		if result, err = parDef.SqlExec(parDef.GetSqlQueryExecFuncParameterValue(ctx, event, dualSysObjectView, func(o string, s string, t string) string {
			return fmt.Sprintf("SELECT CASE WHEN %v < %v THEN '-1' WHEN %v > %v THEN '1' ELSE '0' END AS comparison_result FROM dual", newCompareVal[0], newCompareVal[1], newCompareVal[0], newCompareVal[1])
		}, QueryColValManage)); err != nil {
			return
		}
		return parDef.ResultExec(parDef.NewGetExternalExecFuncParameterValue(ctx, event, result, result.Result, table))
	}
}
func (rows RowsF) IndexPart(ctx context.Context) (result global.Return, err error) {
	var (
		event          = "[IndexPart]"
		res            global.Return
		selectCol      []string
		selectColAs    []string
		whereCondition []string
		indexP         parDef.IndexPart
	)
	defer func() {
		if r := ref.RecoverPanic(event, recover()); err == nil && r != nil {
			err = r
		}
	}()
	switch meta := parDef.GetFuncParameterValue(ctx, parDef.GetMetaParameterValue()); meta.(type) {
	case parDef.IndexPart:
		indexP = meta.(parDef.IndexPart)
	default:
		err = ref.ErrAddPrintf(event, errors.New(fmt.Sprintf("type not matched. curry type is %v", reflect.TypeOf(meta))))
		return
	}
	LimitSeq1 := atomic.LoadInt64(indexP.Limit.Pagination) + 1
	if res, err = rows.SelectIdxCol(ctx); err != nil {
		err = ref.ErrAddPrintf(event, err)
		return
	} else if res.Result == nil {
		return
	} else {
		selectCol, selectColAs = res.Result.([][]string)[0], res.Result.([][]string)[1]
	}
	if whereCondition, err = newWhereGenerate(parDef.GetParameterValueAnyToString(parDef.GetFuncParameterValue(ctx, parDef.GetTableWhereSqlParameterValue())), indexP.WhereGenerate); err != nil {
		err = ref.ErrAddPrintf(event, err)
		return
	}
	if len(whereCondition) == 0 {
		whereCondition = append(whereCondition, fmt.Sprintf("\"%s\" IS NOT NULL ", parDef.GetParameterValueAnyToStringGarth(parDef.GetFuncParameterValue(ctx, parDef.IndexColumnNameParameterValue))[0]))
	}
	var _, table = parDef.GetExecFuncParameterValueBase(ctx)
	select {
	case <-ctx.Done():
		err = ctx.Err()
		return
	default:
		if result, err = parDef.SqlExec(parDef.GetSqlQueryExecFuncParameterValue(ctx, event, dualSysObjectView, func(o string, s string, t string) string {
			return fmt.Sprintf("select * from ( \n"+
				"select %v,rownum rn from ( \n"+
				"select %v %s from ( \n"+
				"select %v from %v %v T where 1 = 1 %v) T %s %s) t \n"+
				"where rownum<=%d) \n"+
				"where rn>%d",
				newResultCol(selectColAs, "t"), newHitSpecify(indexP.Index.IndexName, parDef.GetParameterValueAnyToString(parDef.GetFuncParameterValue(ctx, parDef.GetPartitionParameterValue()))), strings.Join(selectCol, ","),
				newSelectCol(parDef.GetParameterValueAnyToStringGarth(parDef.GetFuncParameterValue(ctx, parDef.GetIndexColumnNameParameterValue()))), tableObject(parDef.GetExecFuncParameterValueBaseP(ctx)),
				specifyScn(parDef.GetParameterValueAnyToString(parDef.GetFuncParameterValue(ctx, parDef.GetTablePositParameterValue()))), rowsLimitC(parDef.GetParameterValueAnyToInt(parDef.GetFuncParameterValue(ctx, parDef.GetTableLimitParameterValue()))),
				newWhereSplicing(whereCondition), newOrderByNull(indexP.WhereGenerate.NullBool, parDef.GetParameterValueAnyToStringGarth(parDef.GetFuncParameterValue(ctx, parDef.IndexColumnNameParameterValue))),
				LimitSeq1,
				atomic.LoadInt64(indexP.Limit.Pagination))
		}, QueryColValManage)); err != nil {
			return
		}
		return parDef.ResultExec(parDef.NewGetExternalExecFuncParameterValue(ctx, event, result, result.Result, table))
	}
}
func (rows RowsF) SelectRowsSql(ctx context.Context) (result global.Return, err error) {
	var (
		res                       global.Return
		event                     = "[Oracle.SelectRowsSql]"
		w                         = []string{" "}
		selectCol, whereCondition []string
		orderByCol                string
		s                         parDef.IndexPart
		indexP                    parDef.IndexPart
	)
	defer func() {
		if r := ref.RecoverPanic(event, recover()); err == nil && r != nil {
			err = r
		}
	}()
	var schema, table = parDef.GetExecFuncParameterValueBase(ctx)
	switch meta := parDef.GetFuncParameterValue(ctx, parDef.GetMetaParameterValue()); meta.(type) {
	case parDef.IndexPart:
		indexP = meta.(parDef.IndexPart)
	default:
		err = ref.ErrAddPrintf(event, fmt.Errorf("type not matched"))
		log.ErrorLog().Error(event, getTableName(schema, table), fmt.Errorf("type not matched. curry type is %v expect type is %v ", reflect.TypeOf(meta), "parDef.IndexPart"))
		return
	}
	select {
	case <-ctx.Done():
		err = ctx.Err()
		return
	default:
		if res, err = rows.SelectAllCol(ctx); err != nil {
			err = ref.ErrAddPrintf(event, err)
			return result, err
		} else if res.Result == nil {
			return result, err
		} else {
			selectCol = res.Result.([]string)
		}
		whereCondition, err = newWhereGenerate(parDef.GetParameterValueAnyToString(parDef.GetFuncParameterValue(ctx, parDef.GetTableWhereSqlParameterValue())), indexP.WhereGenerate)
		orderByCol, err = newOrderBY(s.WhereGenerate)
		result.Result = fmt.Sprintf("select %v %v \n"+
			"from %v %v T \n"+
			"where 1 = 1 %v \n"+
			"%v",
			newHitSpecify("", parDef.GetParameterValueAnyToString(parDef.GetFuncParameterValue(ctx, parDef.GetPartitionParameterValue()))), strings.Join(selectCol, ","),
			tableObject(parDef.GetExecFuncParameterValueBaseP(ctx)), specifyScn(parDef.GetParameterValueAnyToString(parDef.GetFuncParameterValue(ctx, parDef.GetTablePositParameterValue()))),
			strings.Join(append(w, whereCondition...), " and "),
			orderByCol)
		log.MainLog().Debug(event, fmt.Sprintf(" sql is %v", result.Result))
		return result, nil
	}
}

func (rows RowsF) ReadData(ctx context.Context) (result global.Return, err error) {
	var event = "[ReadData]"
	defer func() {
		if r := ref.RecoverPanic(event, recover()); err == nil && r != nil {
			err = r
		}
	}()
	var execSql []string
	if parDef.GetFuncParameterValue(ctx, parDef.GetMetaParameterValue()) == nil {
		log.MainLog().Warn(event, "no data to read")
		return
	}
	switch meta := parDef.GetFuncParameterValue(ctx, parDef.GetMetaParameterValue()); meta.(type) {
	case string:
		execSql = append(execSql, meta.(string))
	case []string:
		execSql = meta.([]string)
	default:
		err = ref.ErrAddPrintf(event, fmt.Errorf("type not matched"))
		log.ErrorLog().Error(event, getTableName(parDef.GetExecFuncParameterValueBase(ctx)), fmt.Errorf("type not matched. curry type is %v expect type is %v ", reflect.TypeOf(meta), "string or []string"))
		return
	}
	var _, table = parDef.GetExecFuncParameterValueBase(ctx)
	select {
	case <-ctx.Done():
		err = ctx.Err()
		return
	default:
		if result, err = parDef.SqlExec(parDef.GetSqlQueryExecFuncParameterValue(ctx, event, execSql, func(o string, s string, t string) string {
			return o
		}, QueryColValManage)); err != nil {
			return
		}
		log.MainLog().Debug(event, fmt.Sprintf(" sql is %v", execSql))
		return parDef.ResultExec(parDef.NewGetExternalExecFuncParameterValue(ctx, event, result, result.Result, table))
	}
}
func (rows RowsF) ReadMiss(ctx context.Context) (result global.Return, err error) {
	var event = "[ReadMiss]"
	var res global.Return
	defer func() {
		if r := ref.RecoverPanic(event, recover()); err == nil && r != nil {
			err = r
		}
	}()
	var _, table = parDef.GetExecFuncParameterValueBase(ctx)
	select {
	case <-ctx.Done():
		err = ctx.Err()
		return
	default:
		if res, err = rows.SelectAllCol(ctx); err != nil {
			err = ref.ErrAddPrintf(event, err)
			return
		}
		if res.Result == nil {
			log.MainLog().Warn(event, "no data to read")
			return
		}
		if result, err = parDef.SqlExec(parDef.GetSqlQueryExecFuncParameterValue(ctx, event, dualSysObjectView, func(o string, s string, t string) string {
			return fmt.Sprintf("select %v %v \n"+
				"from %v %v T \n"+
				"where 1= 1 %v",
				parallel(parDef.GetParameterValueAnyToString(parDef.GetFuncParameterValue(ctx, parDef.GetTableParallelQueryParameterValue()))), strings.Join(res.Result.([]string), ","),
				tableObject(parDef.GetExecFuncParameterValueBaseP(ctx)), specifyScn(parDef.GetParameterValueAnyToString(parDef.GetFuncParameterValue(ctx, parDef.GetTablePositParameterValue()))),
				rowsLimitC(parDef.GetParameterValueAnyToInt(parDef.GetFuncParameterValue(ctx, parDef.GetTableLimitParameterValue()))))
		}, QueryColValManage)); err != nil {
			err = ref.ErrAddPrintf(event, err)
			return
		}
		log.MainLog().Debug(event, fmt.Sprintf(" sql is %v", result.Sql))
		return parDef.ResultExec(parDef.NewGetExternalExecFuncParameterValue(ctx, event, result, result.Result, table))
	}
}
func (rows RowsF) InsertSql(ctx context.Context) (result global.Return, err error) {
	return
}
func (rows RowsF) insertDataPare(parameter dbPar.ExecSql) (execSql any, err error) {
	var setVariables = []string{"SET session unique_checks=0", "SET session foreign_key_checks=0"}
	switch sqlMeta := parameter.Sql; sqlMeta.(type) {
	case []*string:
		var newExecSql []*string
		for _, v := range setVariables {
			newExecSql = append(newExecSql, &v)
		}
		for _, v := range sqlMeta.([]*string) {
			newExecSql = append(newExecSql, v)
		}
		execSql = newExecSql
	case [][]*string:
		execSql = sqlMeta
	default:
		err = ref.ErrAddPrintf("insertDataPare", errors.New(fmt.Sprintf("type not match. type is %v", reflect.TypeOf(sqlMeta))))
		return
	}
	return
}
func (rows RowsF) Insert(ctx context.Context) (result global.Return, err error) {
	var (
		event   = "[Insert]"
		execSql any
	)
	defer func() {
		if r := ref.RecoverPanic(event, recover()); err == nil && r != nil {
			err = r
		}
	}()
	var parameter dbPar.ExecSql
	switch meta := ctx.Value("key"); meta.(type) {
	case dbPar.ExecSql:
		parameter = meta.(dbPar.ExecSql)
	default:
		err = ref.ErrAddPrintf("Insert", errors.New(fmt.Sprintf("type not match. type is %v", reflect.TypeOf(meta))))
	}
	select {
	case <-ctx.Done():
		err = ctx.Err()
		return
	default:
		if execSql, err = rows.insertDataPare(parameter); err != nil {
			err = ref.ErrAddPrintf(event, err)
			return
		}
		if strings.Contains(parameter.Prefix, "(?") {
			parameter.DbDrive.LobSwitch = true
			parameter.DbDrive.InsertPreFix = parameter.Prefix
		}
		if result, err = newExecInsertSql(event, parameter.DbDrive, execSql); err != nil {
			fmt.Println("---------kdd:", parameter.DbDrive.SqlMode, execSql, err)
		}
		return
	}
}
